/*
 * 文件名：SystemUtils.java
 * 版权：Copyright 2013-2013 Hugedata Tech. Co. Ltd. All Rights Reserved
 * 描述：〈描述〉
 * 修改人：〈修改人〉
 * 修改时间：YYYY-MM-DD
 * 跟踪单号：〈跟踪单号〉
 * 修改单号：〈修改单号〉
 * 修改内容：〈修改内容〉
 */
package com.hugedata.cdnserver.util;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.log4j.Logger;
import org.apache.zookeeper.common.IOUtils;

/**
 * @ClassName: SystemUtils
 * @Description: 系统操作工具类
 * @author LuXiuMin
 * @date 2013-8-13 上午9:10:20
 */
public final class SystemUtils
{
    private final static Logger LOGGER = Logger.getLogger(SystemUtils.class);
    private static Properties props;
    public static final String CONFIG_PATH = "/config.properties";
    private static final String ISP_CONFIG_PATH = "/isp.properties";
    private static final String LOC_CONFIG_PATH = "/loc.properties";
    private static Properties ispProps = null;
    private static Properties locProps = null;

    /**
     * constructor
     */
    private SystemUtils()
    {

    }

    public static BigDecimal getDecimals(double simplenum, double totalnum, int scale)
    {
        if (scale < 0)
        {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(simplenum);
        BigDecimal b2 = new BigDecimal(totalnum);
        BigDecimal divide = new BigDecimal(0);
        try
        {
            divide = b1.divide(b2, scale, BigDecimal.ROUND_DOWN);
        }
        catch (Exception e)
        {
            LOGGER.error("被除数不能为0 " + e);
        }
        return divide;
    }

    public static BigDecimal getDecimalsRoundHalfup(double simplenum, double totalnum, int scale)
    {
        if (scale < 0)
        {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(simplenum);
        BigDecimal b2 = new BigDecimal(totalnum);
        BigDecimal divide = new BigDecimal(0);
        try
        {
            divide = b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP);
        }
        catch (Exception e)
        {
            LOGGER.error("被除数不能为0 " + e);
        }
        return divide;
    }

    /**
     * 判断字符串是否为空
     * 
     * @param str
     *            input param
     * @return boolean
     */
    public static boolean isEmpty(String str)
    {
        return (null == str) || "".equals(str) || "null".equals(str) || " ".equals(str);
    }

    /**
     * 判断字符串不为空
     * 
     * @param str
     *            input param
     * @return boolean
     */
    public static boolean isNotEmpty(String str)
    {
        return !isEmpty(str);
    }

    public static int getSeedsFileLineNumbers(String configFilePath) throws IOException
    {
        int count = 0;
        String seedTopFileName = SystemUtils.getCfg(configFilePath).getProperty("top100_file_name");

        String value;
        BufferedReader b = null;
        try
        {
            b = new BufferedReader(new FileReader(SystemUtils.class.getResource("/").getPath() + seedTopFileName));
            value = b.readLine();
            while (value != null)
            {
                count++;
                value = b.readLine();
            }
        }
        catch (FileNotFoundException e)
        {
            LOGGER.error("读取Top文件失败,文件未找到", e);
        }
        catch (IOException e)
        {
            LOGGER.error("文件读写错误,", e);
        }
        finally
        {
            if (b != null)
            {
                try
                {
                    b.close();
                }
                catch (IOException e)
                {
                    LOGGER.error("", e);
                }
            }
        }
        LOGGER.info("Top文件行数 " + count);
        return count;
    }

    public static String getProp(String key)
    {
        return props.getProperty(key);
    }

    public static String getProp(String key, String defaultValue)
    {
        return props.getProperty(key, defaultValue);
    }

    public static Properties getCfg()
    {
        return props;
    }

    public static Properties getCfg(String filePath) throws IOException
    {
        if (props == null)
        {
            props = new Properties();
            InputStream inputStream = SystemUtils.class.getResourceAsStream(CONFIG_PATH);
            props.load(inputStream);
        }
        return props;
    }

    private static Properties loadIspMsg()
    {
        InputStream in = new BufferedInputStream(SystemUtils.class.getResourceAsStream(ISP_CONFIG_PATH));
        Properties properties = new Properties();
        try
        {
            properties.load(in);
        }
        catch (IOException e)
        {
            LOGGER.error("loadIspMsg exception", e);
        }
        finally
        {
            IOUtils.closeStream(in);
        }
        return properties;
    }

    private static Properties loadLocMsg()
    {
        Properties properties = new Properties();
        InputStream in = new BufferedInputStream(SystemUtils.class.getResourceAsStream(LOC_CONFIG_PATH));
        try
        {
            properties.load(in);
        }
        catch (IOException e)
        {
            LOGGER.error("loadLocMsg exception", e);
        }
        finally
        {
            IOUtils.closeStream(in);
        }
        return properties;
    }

    public static String getYesterDate()
    {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, -1);
        SimpleDateFormat f = new SimpleDateFormat("yyyyMMdd");
        String nowDate = f.format(c.getTime());

        LOGGER.info("getYesterDate " + nowDate);
        return nowDate;
    }

    public static String get24HHString()
    {
        Calendar c = Calendar.getInstance();
        Date date = new Date();
        c.setTime(date);
        SimpleDateFormat f = new SimpleDateFormat("HH");
        String hh = f.format(c.getTime());
        return hh;
    }

    public static String getCurentDate()
    {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, 0);
        SimpleDateFormat f = new SimpleDateFormat("yyyyMMdd");
        String nowDate = f.format(c.getTime());

        LOGGER.info("getCurentDate " + nowDate);
        return nowDate;
    }

    public static String getCurentDateStr()
    {
        Calendar c = Calendar.getInstance();
        SimpleDateFormat f = new SimpleDateFormat("yyyyMMddHHmmss");
        String nowDate = f.format(c.getTime());
        LOGGER.info("getCurentDateStr " + nowDate);
        return nowDate;
    }

    public static Long fromDateStrToLong(String dateStr)
    {
        Long lgLong = 1L;
        SimpleDateFormat f = new SimpleDateFormat("yyyyMMddHHmmss");
        try
        {
            Date date = f.parse(dateStr);
            lgLong = date.getTime();
        }
        catch (ParseException e)
        {
            LOGGER.info("getCurentDateStr " + e);
        }
        return lgLong;
    }

    public static String getYearMonthDay()
    {
        Calendar c = Calendar.getInstance();
        SimpleDateFormat f = new SimpleDateFormat("yyyyMMdd");
        String nowDate = f.format(c.getTime());

        LOGGER.info("getYearMonthDay " + nowDate);
        return nowDate;
    }

    public static boolean isFirstDayOfMonth(String dateString)
    {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Date date = null;
        try
        {
            date = sdf.parse(dateString);
        }
        catch (ParseException e)
        {
            LOGGER.error("Date parse error " + e);
            return false;
        }
        // 得到本月1号
        Calendar cal = Calendar.getInstance();
        cal.setLenient(true);
        cal.setTime(date);
        int dayOfMonth = cal.get(Calendar.DATE);
        if (dayOfMonth == 1)
        {
            return true;
        }
        return false;
    }

    public static String getbeforeYesterday(String dateString)
    {
        Calendar c = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Date date = null;
        try
        {
            date = sdf.parse(dateString);
        }
        catch (ParseException e)
        {
            LOGGER.error("Date parse error" + e);
            return "";
        }
        c.setTime(date);
        c.add(Calendar.DAY_OF_MONTH, -1);
        String beforeYesterday = sdf.format(c.getTime());

        LOGGER.info("getbeforeYesterday " + beforeYesterday);
        return beforeYesterday;
    }

    public static String getDate(final String dataStr)
    {
        Calendar c = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Date date = null;
        try
        {
            date = sdf.parse(dataStr);
        }
        catch (ParseException e)
        {
            LOGGER.error("getDate Parse date Exception " + e);
        }
        c.setTime(date);
        String dateStr = sdf.format(c.getTime());
        return dateStr;
    }

    public static String getTaskEndDate(final Date dataStr)
    {
        String HH23mm59ss59 = "235959";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String formatDate = sdf.format(dataStr) + HH23mm59ss59;
        return formatDate;
    }

    public static String getTaskEndDateOfCrawleTool()
    {
        String endDate = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        String formatDate = sdf.format(new Date());

        Calendar calendar = new GregorianCalendar();
        int actualMaximum = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        endDate = formatDate + actualMaximum + "235959";
        return endDate;
    }

    public static String getTaskBeginTime(final String cfgBeginDate)
    {
        String beginDate = "";
        Date nowDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

        try
        {
            Date sdfDate = sdf.parse(cfgBeginDate);
            boolean flag = sdfDate.before(nowDate);
            // 配置的开始时间早于系统当前时间,使用系统时间
            if (flag == true)
            {
                beginDate = sdf.format(nowDate);
                LOGGER.info("配置的开始时间早于系统当前时间,使用系统时间 " + beginDate);
            }// 配置的开始时间晚于系统当前时间,使用配置时间
            else
            {
                beginDate = sdf.format(sdfDate);
                LOGGER.info("配置的开始时间晚于系统当前时间,使用配置时间 " + beginDate);
            }
        }
        catch (ParseException e)
        {
            LOGGER.error("Date parse error " + e);
        }
        return beginDate;
    }

    public static int getDnsDelayAndQosToolRunNum(String configFilePath, final String beginDate) throws IOException
    {
        int runingNumer = 0;
        // qos,dnsdelay工具运行次数偏移量(只能是正负整数)
        String qosDnsDelayOffset = SystemUtils.getCfg(configFilePath).getProperty("qos_dnsdelay_offset").trim();
        int qosDnsDelayOffsetInt = Integer.valueOf(qosDnsDelayOffset);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        try
        {
            Date beginDateFmt = sdf.parse(beginDate);
            Calendar c = Calendar.getInstance();
            c.setTime(beginDateFmt);
            int hourse = c.get(Calendar.HOUR_OF_DAY);
            runingNumer = 24 - hourse + qosDnsDelayOffsetInt;
        }
        catch (ParseException e)
        {
            LOGGER.error("getDnsDelayAndQosToolRunNum Date parse error " + e);
        }
        return runingNumer;
    }

    /**
     * 判断文件的编码格式
     * 
     * @param fileName
     * @return 文件编码格式
     * @throws Exception
     */
    public static String getFileEncode(final String fileName)
    {
        String code = null;
        try
        {
            BufferedReader bin = new BufferedReader(new InputStreamReader(
                    ClassLoader.getSystemResourceAsStream(fileName)));
            int p = (bin.read() << 8) + bin.read();
            switch (p)
            {
            case 0xefbb:
                code = "UTF-8";
                break;
            case 0xfffe:
                code = "Unicode";
                break;
            case 0xfeff:
                code = "UTF-16BE";
                break;
            default:
                code = "GBK";
            }
        }
        catch (Exception e)
        {
            LOGGER.info("parse top file encode error " + e);
        }
        return code;
    }

    public static String assemblingString(final String str, final String dateStr)
    {
        String tempStr = str;
        String tempDate = dateStr;
        String resultStr = tempStr.substring(0, tempStr.lastIndexOf('/')) + "/" + tempDate
                + tempStr.substring(tempStr.lastIndexOf('/'));
        return resultStr;
    }

    public static String getCurrentYearMonth()
    {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        String yearMonth = sdf.format(date);
        return yearMonth;
    }

    public static String checkIspMatch(String countryAndIspName, String isp)
    {
        // 返回结果: 匹配结果_匹配isp编码

        if (countryAndIspName == null || "".equals(countryAndIspName))
        {
            // 未知
            return "0_00";
        }

        String matchFlag = "2_00";// 不匹配
        Set<Entry<Object, Object>> entrySet = ispProps.entrySet();
        Iterator<Entry<Object, Object>> iterator = entrySet.iterator();
        while (iterator.hasNext())
        {
            Entry<Object, Object> next = iterator.next();
            String tmpIspName = (String) next.getKey();

            // boolean matchRest =
            // Pattern.compile(tmpIspName).matcher(countryAndIspName).find();
            boolean matchRest;
            if (StringUtils.contains(countryAndIspName, tmpIspName))
            {
                matchRest = true;
            }
            else
            {
                matchRest = false;
            }

            if (matchRest)
            {
                String tmpIsp = (String) next.getValue();
                if (isp.equals(tmpIsp))
                { // 匹配
                    matchFlag = "1_" + tmpIsp;
                }
                else
                {
                    // 不匹配
                    matchFlag = "2_" + tmpIsp;
                }
                break;
            }
        }
        return matchFlag;
    }

    public static String checkLocMatch(String matchVal1, String matchVal2)
    {
        // 返回结果: 匹配结果_匹配loc编码
        if (matchVal1 == null || "".equals(matchVal1))
        {
            // 未知
            return "0_0000";
        }

        String matchFlag = "2_0000";// 不匹配
        Set<Entry<Object, Object>> entrySet = locProps.entrySet();
        Iterator<Entry<Object, Object>> iterator = entrySet.iterator();
        while (iterator.hasNext())
        {
            Entry<Object, Object> next = iterator.next();
            String key = (String) next.getKey();
            boolean matchRest = Pattern.compile(key).matcher(matchVal1).matches();
            if (matchRest == false)
            {
                matchRest = key.contains(matchVal1);
            }

            if (matchRest)
            {
                String valOfcfg = (String) next.getValue();
                if (matchVal2.equals(valOfcfg))
                { // 匹配
                    matchFlag = "1_" + matchVal2;
                    break;
                }
                else
                {
                    String stringcfg = valOfcfg.substring(0, 2);
                    String inputIsp = matchVal2.substring(0, 2);
                    if (stringcfg.equals(inputIsp))
                    {
                        // 匹配
                        matchFlag = "1_" + matchVal2;
                        break;
                    }
                    else
                    {
                        // 不匹配
                        matchFlag = "2_" + valOfcfg;
                    }
                }
            }
        }
        return matchFlag;
    }

    public static void setAppConfiguration(Configuration conf, String configFilePath) throws IOException
    {

        Properties properties = SystemUtils.getCfg(configFilePath);

        conf.addResource(SystemUtils.getCfg(configFilePath).getProperty("dataplatform.core-site.path"));
        conf.addResource(SystemUtils.getCfg(configFilePath).getProperty("dataplatform.hdfs-site.path"));
        conf.addResource(SystemUtils.getCfg(configFilePath).getProperty("dataplatform.mapred-site.path"));
        conf.addResource(SystemUtils.getCfg(configFilePath).getProperty("dataplatform.yarn-site.path"));
        conf.addResource(SystemUtils.getCfg(configFilePath).getProperty("dataplatform.hbase-site.path"));

        // Set<Object> keySet = properties.keySet();
        // Iterator<Object> it = keySet.iterator();
        // while (it.hasNext())
        // {
        // String num = it.next().toString();
        // String value = properties.get(num).toString();
        // System.out.println(num + "=" + value);
        // conf.set(num, value);
        // }

        // conf.set("fs.default.name", SystemUtils.getCfg(configFilePath)
        // .getProperty("fs.default.name"));
        // conf.set(
        // "yarn.resourcemanager.resource-tracker.address",
        // SystemUtils.getCfg(configFilePath).getProperty(
        // "yarn.resourcemanager.resource-tracker.address"));
        // conf.set(
        // "yarn.resourcemanager.address",
        // SystemUtils.getCfg(configFilePath).getProperty(
        // "yarn.resourcemanager.address"));
        // conf.set(
        // "yarn.resourcemanager.scheduler.address",
        // SystemUtils.getCfg(configFilePath).getProperty(
        // "yarn.resourcemanager.scheduler.address"));
        // conf.set(
        // "yarn.resourcemanager.admin.address",
        // SystemUtils.getCfg(configFilePath).getProperty(
        // "yarn.resourcemanager.admin.address"));
        // conf.set("hbase.master", SystemUtils.getCfg(configFilePath)
        // .getProperty("hbase.master"));
        // conf.set("mapreduce.application.classpath",
        // "$HADOOP_MAPRED_HOME/*,$HADOOP_MAPRED_HOME/lib/*");
        // conf.set(
        // "yarn.application.classpath",
        // "$HADOOP_CONF_DIR,$HADOOP_COMMON_HOME/*,$HADOOP_COMMON_HOME/lib/*,$HADOOP_HDFS_HOME/*,$HADOOP_HDFS_HOME/lib/*,$HADOOP_YARN_HOME/*,$HADOOP_YARN_HOME/lib/*");
        // conf.set("mapred.child.java.opts", "-Xmx1024m");
        // conf.set(
        // "mapreduce.jobhistory.address",
        // SystemUtils.getCfg(configFilePath).getProperty(
        // "mapreduce.jobhistory.address"));
        // conf.set(
        // "mapreduce.jobhistory.webapp.address",
        // SystemUtils.getCfg(configFilePath).getProperty(
        // "mapreduce.jobhistory.webapp.address"));
        // conf.set("mapred.task.timeout", SystemUtils.getCfg(configFilePath)
        // .getProperty("mapred.task.timeout"));
        // conf.set("yarn.app.mapreduce.am.staging-dir", "user");
    }

    public static String longToDateStr(long lg)
    {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        Date dt = new Date(lg);
        String sDateTime = sdf.format(dt);
        return sDateTime;
    }

    public static String longToDate(long lg)
    {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        Date dt = new Date(lg);
        String sDateTime = sdf.format(dt);
        return sDateTime;
    }
}